package JUC;

/**
 * @author 豆包LU
 * @date 2023/5/8 16:11
 */
import java.util.LinkedList;

public class ProducerConsumerExample {
    // 定义一个共享的缓冲区，用于存储生产者生产的数据
    private LinkedList<Integer> buffer = new LinkedList<>();
    // 定义缓冲区的最大容量
    private int maxSize = 5;

    // 生产者线程，往缓冲区中生产数据
    class Producer implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (buffer) {
                    // 如果缓冲区已经满了，则等待
                    while (buffer.size() == maxSize) {
                        try {
                            buffer.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 生产一个数据并添加到缓冲区中
                    int num = (int) (Math.random() * 100);
                    buffer.add(num);
                    System.out.println("生产者生产了：" + num);
                    // 唤醒所有正在等待的消费者线程
                    buffer.notifyAll();
                }
                // 生产者线程休眠一段时间
                try {
                    Thread.sleep((int) (Math.random() * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 消费者线程，从缓冲区中消费数据
    class Consumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (buffer) {
                    // 如果缓冲区已经空了，则等待
                    while (buffer.size() == 0) {
                        try {
                            buffer.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 从缓冲区中取出一个数据并进行消费
                    int num = buffer.removeFirst();
                    System.out.println("消费者消费了：" + num);
                    // 唤醒所有正在等待的生产者线程
                    buffer.notifyAll();
                }
                // 消费者线程休眠一段时间
                try {
                    Thread.sleep((int) (Math.random() * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ProducerConsumerExample example = new ProducerConsumerExample();
        // 创建并启动两个生产者线程
        Thread producer1 = new Thread(example.new Producer());
        Thread producer2 = new Thread(example.new Producer());
        producer1.start();
        producer2.start();
        // 创建并启动三个消费者线程
        Thread consumer1 = new Thread(example.new Consumer());
        Thread consumer2 = new Thread(example.new Consumer());
        Thread consumer3 = new Thread(example.new Consumer());
        consumer1.start();
        consumer2.start();
        consumer3.start();
    }
}
